home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / macabuse / imlib / texture.c < prev    next >
C/C++ Source or Header  |  1997-05-20  |  10KB  |  287 lines

  1. #include "image.hpp"
  2. #include "video.hpp"
  3. #include "macs.hpp"
  4. #include "event.hpp"
  5. #include <math.h>
  6.  
  7. #define SHB 7
  8.  
  9. class vect
  10. {
  11. public :
  12.   long screenx, screeny, screendx, screendy,
  13.        imagex,  imagey,  imagedx,  imagedy;
  14.   short steps;
  15.   void init(short imagex1,  short imagey1,  short imagex2, short imagey2,
  16.        short screenx1, short screeny1, short screenx2, short screeny2);
  17.   short step();
  18. } ;
  19.  
  20. inline short vect::step()
  21. {
  22.   long oy;
  23.   do
  24.   {
  25.     oy=screeny>>SHB;
  26.     screenx+=screendx;
  27.     screeny+=screendy;
  28.     imagex+=imagedx;
  29.     imagey+=imagedy;
  30.     steps--;
  31.   } while (steps && (screeny>>SHB)==oy);
  32.   return steps>=0;
  33. }
  34.  
  35. void vect::init(short imagex1,  short imagey1,  short imagex2, short imagey2,
  36.        short screenx1, short screeny1, short screenx2, short screeny2)
  37. {
  38.   steps=abs(screeny1-screeny2)+1;
  39.   screenx=(long)screenx1<<SHB;
  40.   screeny=(long)screeny1<<SHB;
  41.   if (screenx2>=screenx1)
  42.     screendx=((long)(screenx2-screenx1+1)<<(SHB*2))/((long)(steps<<SHB));
  43.   else screendx=((long)(screenx2-screenx1-1)<<(SHB*2))/((long)(steps<<SHB));
  44.   if (screeny2>=screeny1)
  45.     screendy=((long)(screeny2-screeny1+1)<<(SHB*2))/((long)(steps<<SHB));
  46.   else
  47.     screendy=((long)(screeny2-screeny1-1)<<(SHB*2))/((long)(steps<<SHB));
  48.   imagex =(long)imagex1<<SHB;
  49.   imagey =(long)imagey1<<SHB;
  50.   if (imagex2>=imagex1)
  51.     imagedx=((long)(imagex2-imagex1)<<(SHB*2))/((long)(steps<<SHB));
  52.   else
  53.     imagedx=((long)(imagex2-imagex1)<<(SHB*2))/((long)(steps<<SHB));
  54.   if (imagey2>=imagey1)
  55.     imagedy=((long)(imagey2-imagey1)<<(SHB*2))/((long)(steps<<SHB));
  56.   else
  57.     imagedy=((long)(imagey2-imagey1)<<(SHB*2))/((long)(steps<<SHB));
  58. }
  59.  
  60.  
  61. void texture_map(image *screen, image *tx, short *points)
  62. {
  63.   vect right[2],left[2];
  64.   unsigned char *sl;
  65.   short l=0,r=0,y,sa,min,max,i,x1,x2,screeny;
  66.   short cx1,cy1,cx2,cy2;
  67.   long ix,iy,idx,idy,steps,scx;
  68.   screen->get_clip(cx1,cy1,cx2,cy2);
  69.   x1=0;
  70.   x2=0;
  71.   for (i=1;i<4;i++)
  72.     if (points[i*2]<points[x1*2])
  73.       x1=i;
  74.     else if (points[i*2]>points[x2*2])
  75.       x2=i;
  76.   min=0;
  77.   max=0;
  78.   for (i=1;i<4;i++)
  79.     if (points[i*2+1]<points[min*2+1])
  80.       min=i;
  81.     else if (points[i*2+1]>points[max*2+1])
  82.       max=i;
  83.  
  84.   if (min==0)
  85.   {
  86.     right[0].init(0,0,tx->width()-1,0,                         points[0],points[1],points[2],points[3]);
  87.     right[1].init(tx->width()-1,0,tx->width()-1,tx->height()-1,points[2],points[3],points[4],points[5]);
  88.     left[0].init(0,0,0,tx->height()-1,                         points[0],points[1],points[6],points[7]);
  89.     left[1].init(0,tx->height()-1,tx->width()-1,tx->height()-1,points[6],points[7],points[4],points[5]);
  90.   }
  91.   else if (min==1)
  92.   {
  93.     right[0].init(tx->width()-1,0,tx->width()-1,tx->height()-1, points[2],points[3],points[4],points[5]);
  94.     right[1].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  95.     left[0].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
  96.     left[1].init(0,0,0,tx->height()-1,                          points[0],points[1],points[6],points[7]);
  97.   } else if (min==2)
  98.   {
  99.     right[0].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  100.     right[1].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
  101.  
  102.     left[0].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
  103.     left[1].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
  104.   } else
  105.   {
  106.     right[0].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
  107.     right[1].init(0,0,tx->width()-1,0,                points[0],points[1],points[2],points[3]);
  108.  
  109.     left[0].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
  110.     left[1].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
  111.   }
  112.  
  113.  
  114.   do
  115.   {
  116.     screeny=right[r].screeny>>SHB;
  117.     if (screeny>=cy1 && screeny<=cy2)
  118.     {
  119.       sl=screen->scan_line(screeny);
  120.       ix=left[l].imagex;
  121.       iy=left[l].imagey;
  122.  
  123.       if (left[l].screenx<right[r].screenx)
  124.       { sa=1; steps=right[r].screenx-left[l].screenx; }
  125.       else { sa=-1; steps=left[l].screenx-right[r].screenx; }
  126.       steps+=1<<SHB;
  127.       if (right[r].imagex>ix)
  128.     idx=((right[r].imagex-ix)<<SHB)/steps;
  129.       else idx=((right[r].imagex-ix)<<SHB)/steps;
  130.  
  131.       if (right[r].imagey>iy)
  132.     idy=((right[r].imagey-iy)<<SHB)/steps;
  133.       else idy=((right[r].imagey-iy)<<SHB)/steps;
  134.       scx=left[l].screenx>>SHB;
  135.  
  136.       steps=steps>>SHB;
  137.       if (left[l].screenx<right[r].screenx)
  138.     sa=1; else sa=-1;
  139.       while (steps--)
  140.       {
  141.     if (scx>=cx1 && scx<=cx2)
  142.       sl[scx]=tx->scan_line(iy>>SHB)[ix>>SHB];
  143.     ix+=idx; iy+=idy;
  144.     scx+=sa;
  145.       }
  146.     }
  147.  
  148.     do
  149.     { y=right[r].screeny>>SHB;
  150.       if (!right[r].step())
  151.     r++;
  152.     } while (r!=2 && y==right[r].screeny>>SHB);
  153.  
  154.     do
  155.     { y=left[l].screeny>>SHB;
  156.       if (!left[l].step())
  157.     l++;
  158.     } while (l!=2 && y==left[l].screeny>>SHB);
  159.  
  160.   } while (r!=2 && l!=2);
  161.  
  162. }
  163.  
  164.  
  165. // slower, but allows transparency textures
  166. void clear_texture_map(image *screen, image *tx, short *points)
  167. {
  168.   vect right[3],left[3];
  169.   unsigned char *sl;
  170.   short l=0,r=0,y,sa,min,max,i,x1,x2,screeny;
  171.   short cx1,cy1,cx2,cy2;
  172.   long ix,iy,idx,idy,steps,scx;
  173.   screen->get_clip(cx1,cy1,cx2,cy2);
  174.   x1=0;
  175.   x2=0;
  176.   for (i=1;i<4;i++)
  177.     if (points[i*2]<points[x1*2])
  178.       x1=i;
  179.     else if (points[i*2]>points[x2*2])
  180.       x2=i;
  181.   min=0;
  182.   max=0;
  183.   for (i=1;i<4;i++)
  184.     if (points[i*2+1]<points[min*2+1])
  185.       min=i;
  186.     else if (points[i*2+1]>points[max*2+1])
  187.       max=i;
  188.  
  189.  
  190.  
  191.   if (min==0)
  192.   {
  193.     right[0].init(0,0,tx->width()-1,0,                         points[0],points[1],points[2],points[3]);
  194.     right[1].init(tx->width()-1,0,tx->width()-1,tx->height()-1,points[2],points[3],points[4],points[5]);
  195.     right[2].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  196.  
  197.     left[0].init(0,0,0,tx->height()-1,                         points[0],points[1],points[6],points[7]);
  198.     left[1].init(0,tx->height()-1,tx->width()-1,tx->height()-1,points[6],points[7],points[4],points[5]);
  199.     left[2].init(tx->width()-1,tx->height()-1,tx->width()-1,0, points[4],points[5],points[2],points[3]);
  200.   }
  201.   else if (min==1)
  202.   {
  203.     right[0].init(tx->width()-1,0,tx->width()-1,tx->height()-1, points[2],points[3],points[4],points[5]);
  204.     right[1].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  205.     right[2].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
  206.  
  207.     left[0].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
  208.     left[1].init(0,0,0,tx->height()-1,                          points[0],points[1],points[6],points[7]);
  209.     left[2].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
  210.   } else if (min==2)
  211.   {
  212.     right[0].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  213.     right[1].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
  214.     right[2].init(0,0,tx->width()-1,0,                          points[0],points[1],points[2],points[3]);
  215.  
  216.     left[0].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
  217.     left[1].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
  218.     left[2].init(0,0,0,tx->height()-1,                          points[0],points[1],points[6],points[7]);
  219.   } else
  220.   {
  221.     right[0].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
  222.     right[1].init(0,0,tx->width()-1,0,                points[0],points[1],points[2],points[3]);
  223.     right[2].init(tx->width()-1,0,tx->width()-1,tx->height(),   points[2],points[3],points[4],points[5]);
  224.  
  225.     left[0].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
  226.     left[1].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
  227.     left[2].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
  228.   }
  229.  
  230.  
  231.   do
  232.   {
  233.     screeny=right[r].screeny>>SHB;
  234.     if (screeny>=cy1 && screeny<=cy2)
  235.     {
  236.       sl=screen->scan_line(screeny);
  237.       ix=left[l].imagex;
  238.       iy=left[l].imagey;
  239.  
  240.       if (left[l].screenx<right[r].screenx)
  241.       { sa=1; steps=right[r].screenx-left[l].screenx; }
  242.       else { sa=-1; steps=left[l].screenx-right[r].screenx; }
  243.       steps+=1<<SHB;
  244.       if (right[r].imagex>ix)
  245.     idx=((right[r].imagex-ix)<<SHB)/steps;
  246.       else idx=((right[r].imagex-ix)<<SHB)/steps;
  247.  
  248.       if (right[r].imagey>iy)
  249.     idy=((right[r].imagey-iy)<<SHB)/steps;
  250.       else idy=((right[r].imagey-iy)<<SHB)/steps;
  251.       scx=left[l].screenx>>SHB;
  252.  
  253.       steps=steps>>SHB;
  254.       if (left[l].screenx<right[r].screenx)
  255.     sa=1; else sa=-1;
  256.       while (steps--)
  257.       {
  258.     if (scx>=cx1 && scx<=cx2)
  259.     {
  260.       unsigned char c=tx->scan_line(iy>>SHB)[ix>>SHB];
  261.       if (c!=current_background)
  262.         sl[scx]=c;
  263.     }
  264.     ix+=idx; iy+=idy;
  265.     scx+=sa;
  266.       }
  267.     }
  268.  
  269.     do
  270.     { y=right[r].screeny>>SHB;
  271.       if (!right[r].step())
  272.     r++;
  273.     } while (r!=2 && y==(right[r].screeny>>SHB));
  274.  
  275.     do
  276.     { y=left[l].screeny>>SHB;
  277.       if (!left[l].step())
  278.     l++;
  279.     } while (l!=2 && y==(left[l].screeny>>SHB));
  280.  
  281.   } while ((r!=2 || l==0) && (l!=2 || r==0));
  282.  
  283. }
  284.  
  285.  
  286.  
  287.